﻿using DevelopAssistant.Common;
using DevelopAssistant.Service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DevelopAssistant.AddIn.DatabaseDocument
{
    public partial class MainForm : ICSharpCode.WinFormsUI.Docking.DockContent
    {
        DigitToChnTextUtils digitToChnTextUtils = new DigitToChnTextUtils();
        DevelopAssistant.Service.DataBaseServer DataBaseServer = null;
        System.Data.DataTable Doctable = new DataTable();

        public MainForm()
        {
            InitializeComponent();
        }

        public MainForm(Form HostWindow, AddInBase Owner, DevelopAssistant.Service.DataBaseServer server)
            : this()
        {
            DataBaseServer = server;           
            Doctable.Columns.Add("字段名称", typeof(string));            
            Doctable.Columns.Add("数据类型", typeof(string));
            Doctable.Columns.Add("是否允许为空",typeof(string));
            Doctable.Columns.Add("默认值",typeof(string));
            Doctable.Columns.Add("备注说明", typeof(string));
        }

        private void btnApply_Click(object sender, EventArgs e)
        {
            NProgressBar.Visible = true;
            label3.Text = "正在准备数据";
            DataSet ds = new DataSet();

            var DatabaseType = NORM.DataBase.DataBaseTypes.SqlDataBase;
            switch (this.DataBaseServer.ProviderName)
            {
                case "System.Data.Sql":
                    DatabaseType = NORM.DataBase.DataBaseTypes.SqlDataBase;
                    break;
                case "System.Data.PostgreSql":
                    DatabaseType = NORM.DataBase.DataBaseTypes.PostgreSqlDataBase;
                    break;
                case "System.Data.Sqlite":
                    DatabaseType = NORM.DataBase.DataBaseTypes.SqliteDataBase;
                    break;
                case "System.Data.MySql":
                    DatabaseType = NORM.DataBase.DataBaseTypes.MySqlDataBase;
                    break;
            }

            System.Threading.Tasks.Task.Run(() => {
                using (var db = NORM.DataBase.DataBaseFactory.Create(this.DataBaseServer.ConnectionString, DatabaseType))
                {
                    List<DataGridViewRow> datalist = new List<DataGridViewRow>();

                    this.dataGridView1.Invoke(new MethodInvoker(() =>
                    {
                        foreach (DataGridViewRow row in this.dataGridView1.Rows)
                        {
                            var value = row.Cells[0].Value;
                            if (value != null && Convert.ToBoolean(value))
                            {
                                datalist.Add(row);
                            }
                        }
                    }));

                    int index = 0;
                    int total = datalist.Count;

                    try
                    {
                        foreach (DataGridViewRow row in datalist)
                        {
                            index++;
                            string name = row.Cells[3].Value + "";
                            var data = TransportDocumentTable(db.GetTableObject(name), GetChineseNumericName(index, name));
                            ds.Tables.Add(data);                            
                            this.Invoke(new MethodInvoker(delegate ()
                            {
                                label4.Text = "已完成 " + (index * 1.0 / total * 100).ToString("N2") + " %";
                            }));

                        }
                    }
                    catch(Exception ex)
                    {
                        DevelopAssistant.Common.NLogger.WriteToLine(ex.Message, "导出数据库文档", DateTime.Now, ex.Source, ex.StackTrace);
                    }

                    if (ds.Tables.Count != total)
                    {
                        this.Invoke(new MethodInvoker(delegate () {
                            MessageBox.Show("数据库文档导出数据不完整");
                        }));
                    }

                }            
            }).ContinueWith((task) => {
                string savePath = string.Empty;
                this.Invoke(new MethodInvoker(delegate() {

                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.FileName = this.DataBaseServer.DataBaseName;
                    saveFileDialog.Filter = "word 文档|*.docx";
                    if (saveFileDialog.ShowDialog(this).Equals(DialogResult.OK))
                    {                     
                        savePath = saveFileDialog.FileName;
                    }
                
                }));
                if (!string.IsNullOrEmpty(savePath))
                {
                    NpoiHelper.WordOutToFile("数据库 " + this.DataBaseServer.DataBaseName + " 文档", @"templete.docx", savePath, false, ds);
                }              
                this.Invoke(new MethodInvoker(() => { 
                    MessageBox.Show(this, "数据库 " + this.DataBaseServer.DataBaseName + " 文档成功导出", "提示信息", MessageBoxButtons.OK);
                    NProgressBar.Visible = false;
                }));
            });            

        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            OnThemeChanged(new EventArgs());

            if (DataBaseServer != null)
            {
                NProgressBar.Visible = true;
                this.label2.Text = DataBaseServer.Name;               
                System.Threading.Tasks.Task.Run(() =>
                {
                    var DatabaseType = NORM.DataBase.DataBaseTypes.SqlDataBase;
                    switch (this.DataBaseServer.ProviderName)
                    {
                        case "System.Data.Sql":
                            DatabaseType = NORM.DataBase.DataBaseTypes.SqlDataBase;
                            break;
                        case "System.Data.PostgreSql":
                            DatabaseType = NORM.DataBase.DataBaseTypes.PostgreSqlDataBase;
                            break;
                        case "System.Data.Sqlite":
                            DatabaseType = NORM.DataBase.DataBaseTypes.SqliteDataBase;
                            break;
                        case "System.Data.MySql":
                            DatabaseType = NORM.DataBase.DataBaseTypes.MySqlDataBase;
                            break;
                    }
                    using (var db = NORM.DataBase.DataBaseFactory.Create(this.DataBaseServer.ConnectionString, DatabaseType))
                    {
                        var data = db.GetDataBaseObject("U");
                        this.dataGridView1.Invoke(new MethodInvoker(() => {
                            this.dataGridView1.DataSource = data;
                        }));                       
                    }
                }).ContinueWith((task) =>
                {
                    NProgressBar.Invoke(new MethodInvoker(() => {
                        NProgressBar.Visible = false;
                    }));                   
                });
            }
        }       

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            NProgressBar.SetBounds((this.Width - NProgressBar.Width) / 2, (this.Height - 40 - NProgressBar.Height)/2, NProgressBar.Width, NProgressBar.Height);
        }

        private void checkBox1_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                row.Cells[0].Value = checkBox1.Checked;
            }
        }

        private DataTable TransportDocumentTable(DataTable source,string name)
        {
            DataTable result = Doctable.Clone();

            foreach (DataRow row in source.Rows)
            {
                DataRow dataRow = result.NewRow();
                string TypeName = (row["TypeName"] + "").Trim();
                switch (TypeName.ToLower())
                {
                    case "char":
                    case "varchar":
                    case "nvarchar":
                        TypeName = TypeName + "(" + row["Length"] + ")";
                        break;                    
                    case "decimal":
                        TypeName = TypeName + "(18, 0)";
                        break;
                    case "numeric":
                        TypeName = TypeName + "(18, 0)";
                        break;
                    case "binary":
                        TypeName = TypeName + "(" + row["Length"] + ")";
                        break;
                    case "time":
                        TypeName = TypeName + "(" + row["Length"] + ")";
                        break;
                }                
                dataRow["字段名称"] = row["ColumnName"] + "";
                dataRow["数据类型"] = TypeName;
                dataRow["是否允许为空"] = (row["CisNull"] + "");
                dataRow["默认值"] = row["DefaultValue"] + "";
                dataRow["备注说明"] = row["Describ"] + ""; //string.IsNullOrEmpty(row["Describ"] + "") ? row["ColumnName"] + "" : row["Describ"] + "";
                result.Rows.Add(dataRow);
            }

            result.TableName = name;
            return result;
        }

        private string GetChineseNumericName(int index, string name)
        {             
            string result = digitToChnTextUtils.Convert(index.ToString(), false);
            return "" + result + "、表 " + name + "";
        }

        public override void OnThemeChanged(EventArgs e)
        {
            Color foreColor = SystemColors.WindowText;
            Color backColor = SystemColors.Control;
            Color linkColor = System.Drawing.Color.Blue;
            Color toolBackColor = SystemColors.Control;
            string themeName = AppSettings.EditorSettings.TSQLEditorTheme;
            switch (themeName)
            {
                case "Default":
                    foreColor = SystemColors.WindowText;
                    backColor = SystemColors.Control;
                    linkColor = System.Drawing.Color.Blue;
                    toolBackColor = SystemColors.Control;
                    break;
                case "Black":
                    foreColor = Color.FromArgb(240, 240, 240);
                    backColor = Color.FromArgb(045, 045, 048);
                    linkColor = Color.FromArgb(051, 153, 153);
                    toolBackColor = Color.FromArgb(038, 038, 038);
                    break;
            }

            NProgressBar.ForeColor = foreColor;
            NProgressBar.BackColor = toolBackColor;            
            panel1.ForeColor = foreColor;
            panel1.BackColor = backColor;
            btnApply.ForeColor = foreColor;
            btnApply.BackColor = backColor;
            dataGridView1.SetTheme(themeName);

        }

    }
}
